package models

import (
	"bigdevops/src/common"
	"bigdevops/src/config"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"go.uber.org/zap"
	"time"
)

func TokenNext(dbUser *User, c *gin.Context) {

	sc := c.MustGet(common.GIN_CTX_CONFIG_CONFIG).(*config.ServerConfig)

	// 生成jwt的token
	token, err := GenJwtToken(dbUser, sc)
	if err != nil {
		sc.Logger.Error("生成jwt失败!", zap.Error(err))
		common.FailWithMessage("生成jwt失败", c)
		return
	}

	// 构造返回结构体
	userResp := UserLoginResponse{
		User:  dbUser,
		Token: token,
		//ExpiresAt: claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
	}

	common.OkWithDetailed(userResp, "用户登陆成功", c)
}

// 生成jwt
func GenJwtToken(dbUser *User, sc *config.ServerConfig) (string, error) {

	// new 一个claim对象
	c := UserCustomClaims{
		User: dbUser,
		RegisteredClaims: jwt.RegisteredClaims{
			Issuer: sc.JWTC.Issuer, // 签发人
			// 比如默认5分钟过期：第一次生成的时候 过期时间戳，当前时间往后推 过期间隔
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(sc.JWTC.ExpiresDuration)),
		},
	}
	//使用指定的签名方法创建签名对象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)

	//使用指定的secret签名并获得完成的编码后的字符串token
	return token.SignedString([]byte(sc.JWTC.SigningKey))

}

// 根据长 tokenString 解析 jwt
func ParseToken(jwtLongToken string, sc *config.ServerConfig) (*UserCustomClaims, error) {
	tokenClaims, err := jwt.ParseWithClaims(
		jwtLongToken,
		&UserCustomClaims{},
		func(token *jwt.Token) (i interface{}, e error) {
			return []byte(sc.JWTC.SigningKey), nil
		},
	)
	if err != nil {
		sc.Logger.Error("根据长 tokenString 解析 jwt错误",
			zap.Error(err))
		return nil, err
	}

	if claims, ok := tokenClaims.Claims.(*UserCustomClaims); ok && tokenClaims.Valid {
		//sc.Logger.Info("解析jwt", zap.Any("过期时间", claims.RegisteredClaims.ExpiresAt))
		return claims, nil
	}

	return nil, err

}
